﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace 光通信串口调试助手
{
    public partial class Frm_Main : DMSkin.MetroForm
    {
        public Frm_Main()
        {
            InitializeComponent();
        }
        Frm_Help fh = null;         //帮助窗体
        Class.Var_Monitor _cvm;      //变量变更事件
        bool _b_fix = false;        //窗体是否固定
        Class.Class_Sys_Info _csi;      //配置参数类

        /// <summary>
        /// 初始函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Frm_Main_Load(object sender, EventArgs e)
        {
            Hide();         //隐藏
            Application.DoEvents();
            //主窗体加载
            //Thread.Sleep(100);
            Class.Class_Splasher.Status = "系统初始化...";
            Application.DoEvents();
            //Thread.Sleep(500);
            Class.Class_Splasher.Status = "正在读取配置文件...";
            Application.DoEvents();

            Sys_Init();         //系统初始化

            //Thread.Sleep(500);
            Class.Class_Splasher.Close();
            _cvm = new Class.Var_Monitor(mlab_RCV_Count, mlab_Sed_Count);
            lab_SysTmr.Text = DateTime.Now.ToString("yyyy年MM月dd日 hh:mm");
            this.Show();
            this.Opacity = 1;
            Application.DoEvents();
            this.Activate();
        }

        /// <summary>
        /// 系统初始化
        /// </summary>
        private void Sys_Init()
        {
            _csi = new Class.Class_Sys_Info();
            mcb_Show_Time.Checked = _csi.ShowTime;
            mcb_Show_Now.Checked = _csi.Fresh;
            mcb_Show_Hex.Checked = _csi.ShowHex;
            mcb_Color.Checked = _csi.BlackWhite;
            mcb_Send_Hex.Checked = _csi.SendHex;
            mcb_Send_NewLIne.Checked = _csi.SendNewLine;
            ndp_Times.Value = _csi.STime;
        }

        /// <summary>
        /// 保存系统设置
        /// </summary>
        private void Save_Config()
        {
            _csi.ShowTime = mcb_Show_Time.Checked;
            _csi.Fresh = mcb_Show_Now.Checked;
            _csi.ShowHex = mcb_Show_Hex.Checked;
            _csi.BlackWhite = mcb_Color.Checked;
            _csi.SendHex = mcb_Send_Hex.Checked;
            _csi.SendNewLine = mcb_Send_NewLIne.Checked;
            _csi.STime =(int)ndp_Times.Value;
            _csi.Save();
        }

        /// <summary>
        /// 委托
        /// </summary>
        public delegate void CallBackDelegate(int _Msg);
        bool _sign_Sta = false;
        /// <summary>
        /// 回调函数
        /// </summary>
        /// <param name="message"></param>
        private void CallBack(int _Msg)
        {
            Invoke((Action)delegate ()
            {
                switch (_Msg)
                {
                    case 0:             
                    case 1:                //刷新连接 //握手成功
                        lab_Sta.Text = "连接";
                        _sign_Sta = false;
                        break;
                    case 2:
                        lab_Model.Text = "字符串";
                        _sign_Sta = false;
                        break;
                    case 3:
                        lab_Model.Text = "音频";
                        _sign_Sta = false;
                        break;
                }
            });
        }

        /// <summary>
        /// 数据接收
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void serial_Con1_Serial_Received(object sender, EventArgs e)
        {
            CallBackDelegate cdb = new CallBackDelegate(CallBack);
            Class.Class_Msg_Deal cmd = new Class.Class_Msg_Deal(sender.ToString());
            Thread _th = new Thread(cmd.Thread_Parse);
            _th.Start(cdb);
            Invoke((Action)delegate ()
            {
                string _str = sender.ToString();
                if (mcb_Show_Hex.Checked)               //是否十六进制显示
                {
                    _str = Class.Data_Convert.StringToHexString(_str,Encoding.ASCII);
                }
                if (mcb_Show_Time.Checked)                  //是否需要显示时间戳  显示时间戳换行
                {
                    dtbx_Receive.Text += "【" + DateTime.Now.ToLongTimeString() + "】: " + _str + "\r\n";
                }
                else
                    dtbx_Receive.Text += _str;

                _cvm.Rcv_Count += sender.ToString().Length;
                if (mcb_Show_Now.Checked)
                {
                    dtbx_Receive.SelectionStart = dtbx_Receive.Text.Length;
                    dtbx_Receive.ScrollToCaret();
                }
                Application.DoEvents();
            });
        }

        /// <summary>
        /// 清空发送区按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dbtn_Clear_Click(object sender, EventArgs e)
        {
            dtbx_Send.Text = "";
        }

        /// <summary>
        /// 清空接收区
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dbtn_Clear_RCV_Click(object sender, EventArgs e)
        {
            dtbx_Receive.Text = "";
        }


        /// <summary>
        /// 系统时间显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tmr_Sys_Tick(object sender, EventArgs e)
        {
            lab_SysTmr.Text = DateTime.Now.ToString("yyyy年MM月dd日 hh:mm");
            Application.DoEvents();
        }

        /// <summary>
        /// 串口状态改变事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void serial_Con1_Serial_StataChange(object sender, EventArgs e)
        {
            if ((bool)sender)
            {
                lab_Tip.Text = "已连接";
                mcb_Send_OnTime.Enabled = true;
            }
            else
            {
                lab_Tip.Text = "未连接";
                mcb_Send_OnTime.Enabled = false;
            }
        }

        /// <summary>
        /// 发送按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Send_Click(object sender, EventArgs e)
        {
            if (dtbx_Send.Text == "") return;               //无数据
            if (!serial_Con1.Serial_Sta)        //串口未打开
            {
                DMSkin.MetroMessageBox.Show(this, "串口未打开，请打开串口后继续。", "提示");
                return;
            }
            string _str_Send = dtbx_Send.Text;
            if (mcb_Send_Hex.Checked)
            {
                //发送16进制
                _str_Send = _str_Send.Trim();
                _str_Send = Class.Data_Convert.HexStringToString(_str_Send,Encoding.ASCII);
            }
            Send_Data(_str_Send + (mcb_Send_NewLIne.Checked ? "\r\n" : ""));
        }


        /// <summary>
        /// 发送
        /// </summary>
        /// <param name="_byte"></param>
        public void Send_Data(byte[] _byte)
        {
            if (serial_Con1.Serial_Write(_byte, 0, _byte.Length))
            {
                _cvm.Send_Count += _byte.Length;
            }
        }
        public void Send_Data(string _str)
        {
            Send_Data(Encoding.Default.GetBytes(_str));
        }


        #region 清除计数
        private void mlab_RCV_Count_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            _cvm.Rcv_Count = 0;
        }

        private void mlab_Sed_Count_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            _cvm.Send_Count = 0;
        }
        #endregion


        /// <summary>
        /// 按键监视
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dtbx_Send_KeyPress(object sender, KeyPressEventArgs e)
        {
            //MessageBox.Show(dtbx_Send.SelectedText);
            if ((int)e.KeyChar > 127)
            {
                e.Handled = true;           //表示为汉字
                return;
            }
            if (mcb_Send_Hex.Checked)
            {
                if ("0123456789ABCDEF\b".IndexOf(e.KeyChar = char.ToUpper(e.KeyChar)) < 0)
                {
                    e.Handled = true;
                    return;
                    //e.KeyChar = '\0';
                }
                if (e.KeyChar != '\b'&& e.KeyChar != ' ')
                {
                    string _str_ls = dtbx_Send.Text.Replace(" ", "");       //替换所有空格
                    //string _ls = dtbx_Send.Text.Remove(dtbx_Send.SelectionStart, dtbx_Send.SelectionLength);
                    if (_str_ls != "" && dtbx_Send.SelectionLength == 0&& _str_ls.Length % 2 == 0)
                    {
                        dtbx_Send.Text += " ";
                        dtbx_Send.SelectionStart = dtbx_Send.Text.Length;
                    }
                }
            }
        }


        /// <summary>
        /// 勾选16进制发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mcb_Send_Hex_CheckedChanged(object sender, EventArgs e)
        {
            if (dtbx_Send.Text != "")
            {
                if (mcb_Send_Hex.Checked)
                {
                    dtbx_Send.Text= Class.Data_Convert.StringToHexString(dtbx_Send.Text,Encoding.ASCII);
                }
                else
                {
                    dtbx_Send.Text = Class.Data_Convert.HexStringToString(dtbx_Send.Text, Encoding.ASCII);
                }
            }
        }

        /// <summary>
        /// 定时发送勾选
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mcb_Send_OnTime_CheckedChanged(object sender, EventArgs e)
        {
            if (mcb_Send_OnTime.Checked)
            {
                dbtn_Clear.Enabled = false;
                btn_Send.Enabled = false;
                dtbx_Send.Enabled = false;
                mcb_Send_Hex.Enabled = false;
                mcb_Send_NewLIne.Enabled = false;
                serial_Con1.Enabled = false;
                ndp_Times.Enabled = false;
                tmr_Send_OnTime.Interval = (int)ndp_Times.Value;
                tmr_Send_OnTime.Start();
            }
            else
            {
                dbtn_Clear.Enabled = true;
                btn_Send.Enabled = true;
                dtbx_Send.Enabled = true;
                mcb_Send_Hex.Enabled = true;
                mcb_Send_NewLIne.Enabled = true;
                serial_Con1.Enabled = true;
                ndp_Times.Enabled = true;
                tmr_Send_OnTime.Stop();
            }
        }

        /// <summary>
        /// 定时发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tmr_Send_OnTime_Tick(object sender, EventArgs e)
        {
            btn_Send_Click(null, null);
        }


        /// <summary>
        /// 帮助链接点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void llab_SWorld_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            //调用系统默认的浏览器   
            System.Diagnostics.Process.Start("http://blog.csdn.net/baidu_26678247");
        }

        /// <summary>
        /// 显示样式切换
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mcb_Color_CheckedChanged(object sender, EventArgs e)
        {
            if (mcb_Color.Checked)
            {
                dtbx_Receive.BackColor = Color.Black;
                dtbx_Receive.ForeColor = Color.White;
            }
            else
            {
                dtbx_Receive.BackColor = Color.White;
                dtbx_Receive.ForeColor = Color.Black;
            }
        }

        /// <summary>
        /// 关闭窗体前判断串口是否关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Frm_Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (serial_Con1.Serial_Sta)
            {
                DMSkin.MetroMessageBox.Show(this,"串口未关闭，请关闭串口后继续。","提示");
                e.Cancel = true;
            }
            Save_Config();
        }
       
        /// <summary>
        /// 使窗体始终保持最前端
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_fix_Click(object sender, EventArgs e)
        {
            if (_b_fix)
            {
                //btn_fix.BackColor = Color.White;
                //btn_fix.ForeColor = Color.Black;
                btn_fix.BackgroundImage = Properties.Resources.unfix;
                Application.DoEvents();
                this.TopMost = false;
                mtt_Main.SetToolTip(btn_fix, "置顶");
                _b_fix = false;
            }
            else
            {
                //btn_fix.BackColor = Color.SkyBlue;
                //btn_fix.ForeColor = Color.White;
                btn_fix.BackgroundImage = Properties.Resources.fix;
                Application.DoEvents();
                this.TopMost = true;
                mtt_Main.SetToolTip(btn_fix, "取消置顶");
                _b_fix = true;
            }
        }

        /// <summary>
        /// 帮助按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Help_Click(object sender, EventArgs e)
        {
            if (fh == null || fh.IsDisposed)
            {
                fh = new Frm_Help();
                fh.Owner = this;
                Class.Class_Magnetic tt = new Class.Class_Magnetic(this, fh, Class.MagneticPosition.Right);
                fh.Show();
            }
            else
            {
                fh.Close();
                fh.Dispose();
                fh = null;
            }
        }

        /// <summary>
        /// 发送连接请求
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Hand_Click(object sender, EventArgs e)
        {
            if (!serial_Con1.Serial_Sta)
            {
                DMSkin.MetroMessageBox.Show(this, "请打开串口后继续！", "提示");
                return;
            }
            if (_csi.Str_HandShake != "")
            {
                Send_Data(_csi.Str_HandShake + "\r\n");
                tmr_Fresh_Con.Start();
                _sign_Sta = true;
            }
        }

        /// <summary>
        /// 切换字符串发送
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Send_String_Click(object sender, EventArgs e)
        {
            if (!serial_Con1.Serial_Sta)
            {
                DMSkin.MetroMessageBox.Show(this, "请打开串口后继续！", "提示");
                return;
            }
            if (_csi.Str_ModelStr != "")
            {
                Send_Data(_csi.Str_ModelStr + "\r\n");
                tmr_Fresh_Con.Start();
                _sign_Sta = true;
            }
        }

        /// <summary>
        /// 切换音频发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Send_Voice_Click(object sender, EventArgs e)
        {
            if (!serial_Con1.Serial_Sta)
            {
                DMSkin.MetroMessageBox.Show(this, "请打开串口后继续！", "提示");
                return;
            }
            if (_csi.Str_ModelVoice != "")
            {
                Send_Data(_csi.Str_ModelVoice + "\r\n");
                tmr_Fresh_Con.Start();
                _sign_Sta = true;
            }
        }

        /// <summary>
        /// 双击刷新连接状态
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lab_Sta_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (!serial_Con1.Serial_Sta)
            {
                DMSkin.MetroMessageBox.Show(this, "请打开串口后继续！", "提示");
                return;
            }
            Send_Data(_csi.Str_CheckCon+"\r\n");
            tmr_Fresh_Con.Start();
            _sign_Sta = true;
        }


        /// <summary>
        /// 检测连接回执，1秒没有回执，表示断开连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tmr_Fresh_Con_Tick(object sender, EventArgs e)
        {
            if (_sign_Sta)
            {
                lab_Sta.Text = "断开";
                tmr_Fresh_Con.Stop();
                _sign_Sta = false;
            }
        }

        /// <summary>
        /// 文字改变  颜色改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lab_Sta_TextChanged(object sender, EventArgs e)
        {
            if (lab_Sta.Text == "连接")
            {
                lab_Sta.ForeColor = Color.Green;
            }
            else
            {
                lab_Sta.ForeColor = Color.Red;
            }
        }
    }

}
